package ru.nlezhnev;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/*
 * mysql> CREATE TABLE java_objects ( 
 * id INT AUTO_INCREMENT, 
 * name varchar(128), 
 * object_value BLOB, 
 * primary key (id));
 **/

public class DataSaver {
	static final String WRITE_OBJECT_SQL = "INSERT INTO java_objects(name, object_value) VALUES (?, ?)";

	static final String READ_OBJECT_SQL = "SELECT object_value FROM java_objects WHERE id = ?";

	public static long writeJavaObject(Connection conn, Object object)
			throws Exception {
		String className = object.getClass().getName();
		PreparedStatement pstmt = conn.prepareStatement(WRITE_OBJECT_SQL, Statement.RETURN_GENERATED_KEYS);
		
		ByteArrayOutputStream byteStream = new ByteArrayOutputStream();	      
		GZIPOutputStream gz = new GZIPOutputStream(byteStream);
		ObjectOutputStream objStream = new ObjectOutputStream(gz);		
		objStream.writeObject(object);
		objStream.flush();
		objStream.close();
		gz.finish();

		// set input parameters
		pstmt.setString(1, className);
		pstmt.setBytes(2, byteStream.toByteArray());// setObject(2, object);
		pstmt.executeUpdate();

		// get the generated key for the id
		ResultSet rs = pstmt.getGeneratedKeys();
		int id = -1;
		if (rs.next()) {
			id = rs.getInt(1);
		}

		rs.close();
		pstmt.close();
//		System.out.println("writeJavaObject: done serializing: " + className);
		return id;
	}
	
    /**
     * This class will de-serialize a java object from the database
     */
    public static Object readJavaObject(Connection conn, long id)
            throws Exception {
        PreparedStatement pstmt = conn.prepareStatement(READ_OBJECT_SQL);
        pstmt.setLong(1, id);
        ResultSet rs = pstmt.executeQuery();
        rs.next();
        byte[] buf = rs.getBytes("object_value");
        ObjectInputStream objectIn = null;
        if (buf != null)
            objectIn = new ObjectInputStream(new GZIPInputStream(new ByteArrayInputStream(buf)));
        Object object = objectIn.readObject();
        rs.close();
        pstmt.close();
//        System.out.println("Deserialization Successful."+
//                            "\nDeserialized Class: "+ className);
        return object;
    }
}
